package com.jzqf.harmonydemo.library.camera;

import com.jzqf.harmonydemo.utils.ArrayUtil;
import com.jzqf.harmonydemo.utils.LogUtil;
import com.jzqf.harmonydemo.utils.ToastUtil;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.*;
import ohos.media.camera.params.Metadata;
import ohos.media.camera.params.ParameterKey;
import ohos.media.camera.params.PropertyKey;
import ohos.media.camera.params.ResultKey;
import ohos.media.image.ImageReceiver;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.Size;
import ohos.security.SystemPermission;
import ohos.security.permission.NeedsPermission;

import java.util.*;

public class CameraManager {
    private final String TAG = CameraManager.class.getSimpleName();
    private final Context context;
    private EventHandler eventHandler;
    private Camera cameraDevice;
    private SurfaceProviderPreview surfaceProvider;
    private Surface previewSurface;
    private ImageReceiver imageReceiver;
    private CameraKit cameraKit;
    private ImageReceiver.IImageArrivalListener imageArrivalListener;

    @NeedsPermission(value = SystemPermission.CAMERA)
    public CameraManager(Context context) {
        this.context = context;
        eventHandler = new EventHandler(EventRunner.create("camera_front"));
    }

    public void init(SurfaceProviderPreview surfaceProvider) {
        this.surfaceProvider = surfaceProvider;
        // 获取CameraKit对象
        cameraKit = CameraKit.getInstance(context);
        if (cameraKit == null) {
            // 处理cameraKit获取失败的情况
            ToastUtil.show(context, "未获取到相机对象");
            return;
        }
        String[] cameraIds = cameraKit.getCameraIds();
        if (cameraIds.length <= 0) {
            LogUtil.e(TAG, "没有可用的相机");
            return;
        }
        surfaceProvider.getSurfaceOps().get().addCallback(surfaceOpsCallback);
    }

    private void openCamera(String cameraId) {
        getSupport(cameraId);
        //TODO 相机预览画面变形
        Size size = getSupportSize(cameraId, surfaceProvider.getWidth(), surfaceProvider.getHeight());
        surfaceProvider.setAspectRatio(size.width, size.height);
        //要求宽度>高度
        imageReceiver = ImageReceiver.create(size.width, size.height, ImageFormat.YUV420_888, 5);
        imageReceiver.setImageArrivalListener(imageArrivalListener);
        cameraKit.createCamera(cameraId, cameraStateCallback, eventHandler);
    }

    private final SurfaceOps.Callback surfaceOpsCallback = new SurfaceOps.Callback() {
        @Override
        public void surfaceCreated(SurfaceOps surfaceOps) {
            if (surfaceOps != null) {
                surfaceOps.setFixedSize(surfaceProvider.getHeight(), surfaceProvider.getWidth());
            }
            openCamera(cameraKit.getCameraIds()[0]);
        }

        @Override
        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

        }

        @Override
        public void surfaceDestroyed(SurfaceOps surfaceOps) {
            LogUtil.d(TAG, "surfaceOpsCallback surfaceDestroyed");
        }
    };
    private final CameraStateCallback cameraStateCallback = new CameraStateCallback() {
        @Override
        public void onCreated(Camera camera) {
            super.onCreated(camera);
            cameraDevice = camera;
            previewSurface = surfaceProvider.getSurfaceOps().get().getSurface();
            if (previewSurface == null) {
                LogUtil.e(TAG, "create camera filed, preview surface is null");
                return;
            }
            CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder();
            if (cameraConfigBuilder == null) {
                LogUtil.e(TAG, "cameraConfigBuilder is null.");
                return;
            }
            //配置预览的surface
            cameraConfigBuilder.addSurface(previewSurface);
            //配置拍照的surface
            cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
            //配置结果帧的回调
            cameraConfigBuilder.setFrameStateCallback(frameStateCallback, eventHandler);
            //相机设备设置
            camera.configure(cameraConfigBuilder.build());
        }

        @Override
        public void onCreateFailed(String cameraId, int errorCode) {
            super.onCreateFailed(cameraId, errorCode);
            LogUtil.d(TAG, "onCreateFailed errorCode=" + errorCode);
        }

        @Override
        public void onConfigured(Camera camera) {
            super.onConfigured(camera);
            CameraAbility cameraAbility = cameraKit.getCameraAbility(camera.getCameraId());
            //预览控件的宽高中心点
            int centerX = surfaceProvider.getWidth() / 2;
            int centerY = surfaceProvider.getHeight() / 2;
            FrameConfig.Builder frameConfigBuilder = camera.getFrameConfigBuilder(1);
            frameConfigBuilder.addSurface(previewSurface);
            frameConfigBuilder.setImageRotation(0);
            //校验镜头支持的对焦模式
            if (ArrayUtil.contains(cameraAbility.getSupportedAfMode(), Metadata.AfMode.AF_MODE_CONTINUOUS)) {
                //连续触发自动对焦，Rect区域
                frameConfigBuilder.setAfMode(Metadata.AfMode.AF_MODE_CONTINUOUS,
                        new Rect(centerX - 200, centerY - 200, centerX + 200, centerY + 200));
            }
            //frameConfigBuilder.setAfTrigger(Metadata.AfTrigger.AF_TRIGGER_START);
            //设置画面缩放，在相机支持的缩放范围内
//            if(10f<Arrays.stream(cameraAbility.getSupportedZoom())){
//
//            }
            frameConfigBuilder.setZoom(10.0f);
            //启动单帧循环捕获
            camera.triggerLoopingCapture(frameConfigBuilder.build());
        }

        @Override
        public void onPartialConfigured(Camera camera) {
            super.onPartialConfigured(camera);
            //当使用了 addDeferredSurfaceSize 配置了相机，会接到此回调
        }

        @Override
        public void onConfigureFailed(Camera camera, int errorCode) {
            super.onConfigureFailed(camera, errorCode);
            LogUtil.d(TAG, "CameraStateCallback onConfigureFailed errorCode=" + errorCode);
        }

        @Override
        public void onReleased(Camera camera) {
            super.onReleased(camera);
            LogUtil.d(TAG, "释放相机");
        }

        @Override
        public void onFatalError(Camera camera, int errorCode) {
            super.onFatalError(camera, errorCode);
            LogUtil.e(TAG, "CameraStateCallback onFatalError,errorCode=" + errorCode);
        }

        @Override
        public void onCaptureRun(Camera camera) {
            super.onCaptureRun(camera);
        }

        @Override
        public void onCaptureIdle(Camera camera) {
            super.onCaptureIdle(camera);
        }
    };

    private final FrameStateCallback frameStateCallback = new FrameStateCallback() {
        @Override
        public void onFrameStarted(Camera camera, FrameConfig frameConfig, long frameNumber, long timestamp) {
            super.onFrameStarted(camera, frameConfig, frameNumber, timestamp);

        }

        @Override
        public void onFrameProgressed(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
            super.onFrameProgressed(camera, frameConfig, frameResult);
        }

        @Override
        public void onFrameFinished(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
            super.onFrameFinished(camera, frameConfig, frameResult);
        }

        @Override
        public void onFrameError(Camera camera, FrameConfig frameConfig, int errorCode, FrameResult frameResult) {
            super.onFrameError(camera, frameConfig, errorCode, frameResult);
        }

        @Override
        public void onCaptureTriggerStarted(Camera camera, int captureTriggerId, long firstFrameNumber) {
            super.onCaptureTriggerStarted(camera, captureTriggerId, firstFrameNumber);
        }

        @Override
        public void onCaptureTriggerFinished(Camera camera, int captureTriggerId, long lastFrameNumber) {
            super.onCaptureTriggerFinished(camera, captureTriggerId, lastFrameNumber);
        }

        @Override
        public void onCaptureTriggerInterrupted(Camera camera, int captureTriggerId) {
            super.onCaptureTriggerInterrupted(camera, captureTriggerId);
        }
    };

    public void setImageArrivalListener(ImageReceiver.IImageArrivalListener listener) {
        this.imageArrivalListener = listener;
    }


    private Size getSupportSize(String cameraId, int width, int height) {
        LogUtil.d(TAG, "控件的尺寸=" + width + ",height=" + height);
        List<Size> sizeList = new ArrayList<>();
        List<Size> supportedSizes = cameraKit.getCameraAbility(cameraId).getSupportedSizes(ImageFormat.YUV420_888);
        for (Size size : supportedSizes) {
            //LogUtil.d(TAG, "支持的width=" + size.width + ",height=" + size.height);
            if (width < height) {
                if (size.width > width) {
                    sizeList.add(size);
                }
            } else {
                if (size.height > width) {
                    sizeList.add(size);
                }
            }
        }
//        return Collections.min(sizeList, new Comparator<Size>() {
//            @Override
//            public int compare(Size sizeA, Size sizeB) {
//                return sizeA.width - sizeB.width;
//            }
//        });
        Size min = Collections.min(sizeList, Comparator.comparingInt(sizeA -> sizeA.width));
        LogUtil.d(TAG, "设置的width=" + min.width + ",height=" + min.height);
        return min;
    }

    private void getSupport(String cameraId) {
        CameraAbility cameraAbility = cameraKit.getCameraAbility(cameraId);
        //获取当前相机支持的自动曝光模式。
        int[] supportedAeMode = cameraAbility.getSupportedAeMode();
        LogUtil.d(TAG, "自动曝光模式supportedAeMode=" + Arrays.toString(supportedAeMode));
        if (supportedAeMode[0] == Metadata.AeMode.AE_MODE_ON) {
            //自动曝光模式已启用
        }
        //获取当前相机支持的自动对焦模式。
        int[] supportedAfMode = cameraAbility.getSupportedAfMode();
        LogUtil.d(TAG, "自动对焦模式supportedAfMode=" + Arrays.toString(supportedAfMode));
        //获取相机支持的人脸检测类型范围。
        int[] supportedFaceDetection = cameraAbility.getSupportedFaceDetection();
        LogUtil.d(TAG, "supportedFaceDetection=" + Arrays.toString(supportedFaceDetection));
        //当前相机支持的闪光灯取值范围。
        int[] supportedFlashMode = cameraAbility.getSupportedFlashMode();
        LogUtil.d(TAG, "supportedFlashMode=" + Arrays.toString(supportedFlashMode));
        //当前相机支持的参数设置。
        List<ParameterKey.Key<?>> supportedParameters = cameraAbility.getSupportedParameters();
        //获取当前相机的属性列表。
        List<PropertyKey.Key<?>> supportedProperties = cameraAbility.getSupportedProperties();
        //获取当前相机支持的参数设置可返回的结果列表。
        List<ResultKey.Key<?>> supportedResults = cameraAbility.getSupportedResults();
        //获取相机支持的变焦范围。
        float[] supportedZoom = cameraAbility.getSupportedZoom();
        LogUtil.d(TAG, "supportedZoom=" + Arrays.toString(supportedZoom));
    }

    /**
     * 释放资源
     */
    public void release() {
        if (cameraDevice != null) {
            cameraDevice.release();
            cameraDevice = null;
        }
        if (imageReceiver != null) {
            imageReceiver.release();
            imageReceiver = null;
        }
        if (eventHandler != null) {
            eventHandler.removeAllEvent();
            eventHandler = null;
        }
    }
}
